namespace ghost {
	/**动画角色，编写基础动画功能，播放动作，行走，站立等*/
	export class AniRole extends Role{				
		public constructor(sceneMgr:SceneManager=null) {
			super(sceneMgr);			
			let s = this;
			s._stsEndListener = new Listener;
		}
		public parseConfig(roleType:number, cfg:any):void
		{
			let s = this;
			super.parseConfig(roleType, cfg);
			s.setConfig(cfg);			
			s._visible = true;
		}
		protected setConfig(cfg:any):void
		{
			let s = this;
			if(cfg.areaRect)			
			{
				s._areaLeft = cfg.areaRect[0];
				s._areaTop = cfg.areaRect[1];
				s._areaRight = s._areaLeft + cfg.areaRect[2];
				s._areaBottom = s._areaTop + cfg.areaRect[3];
			}
			else			
				s._areaLeft = s._areaTop = s._areaRight = s._areaBottom = 0;			
			
			s._areaRowMin = Math.floor((s._absY + s._areaTop) / s._scene.mapAreaSize);
			s._areaColMin = Math.floor((s._absX + s._areaLeft) / s._scene.mapAreaSize);
			s._areaRowMax = Math.floor((s._absY + s._areaBottom) / s._scene.mapAreaSize);
			s._areaColMax = Math.floor((s._absX + s._areaRight) / s._scene.mapAreaSize);

			
			s._autoRotate = cfg.autoRotate==1;
			s._autoRotation = 0;
			s._floatH = s._roleFloatH = cfg.floatH ? cfg.floatH : 0;
		}
		public setSkin(skinObj:any):void
		{
			let s = this;			
			s._skinObj = skinObj;
			s._skinType = skinObj.skinType;						
			s.createSkinPart(skinObj);			
			s.setSts(s._createSts, s._createDir);
		}
		protected createSkinPart(skinObj:any, scl:number=1):void
		{
			let s = this;
			if(skinObj.skinType == SkinType.SEQ)
			{
				let seqImg:SeqSprite;
				seqImg = new SeqSprite(s._scene);		
				seqImg.owner = this;		
				seqImg.globalScl = s.getSceneScale();	
				s._skinPart = <any>seqImg;
				s._skin.addChild(seqImg);	
							
			}
		}
		public getRoleEffect(roleEffId: number): RoleEffect {
			let s = this;
			if (s._roleEffects == null)
				s._roleEffects = new RoleEffectMgr;
			return s._roleEffects.findRoleEffectById(roleEffId);
		}
		public addRoleEffect(e: RoleEffect, remove: boolean = true): void {
			let s = this;
			if (s._roleEffects == null)
				s._roleEffects = new RoleEffectMgr;
			s._roleEffects.addRoleEffect(e, remove);
		}
		public removeRoleEffect(e: RoleEffect): void {
			let s = this;
			if (!s._roleEffects) return;
			s._roleEffects.removeRoleEffect(e);
		}
		public removeRoleEffectById(id: number): void {
			let s = this;
			if (!s._roleEffects) return;
			s._roleEffects.removeRoleEffectById(id);
		}
		public invalidRoleEffect(): void {
			let s = this;
			if (!s._roleEffects)
				return;
			s._roleEffects.invalidRoleEffect();
		}
		protected getSceneScale():number
		{
			return 1;
		}
		public resetSkin(skinObj:any)
		{
			let s= this;
			let clothesConfig:any;	
			s._lastOffsetX = s._lastOffsetY = s._lastOffsetH = 0;//重置动作参数
			s._skinObj = skinObj;
			s._skinType = skinObj.skinType;						
			s._clothesConfig = clothesConfig = Conf.getClothes(skinObj.clothes);
			s._actionConfig = Conf.getAction(skinObj.action);
			if(s._skinType == SkinType.SEQ)
			{		
				let sts: number, direction: number;		
				let seqImg:SeqSprite = <any>s._skinPart;	
				
				sts = clothesConfig[s._sts] ? s._sts : StsType.STAND;
				s._clothes = clothesConfig[sts];
				s._action = Conf.getAction(skinObj.action);					
				// if(s._action == null)
				// 	console.warn("找不到动作配置!状态："+sts+"-角色："+s._roleID);
				// else 
				if(s._clothes == null)
					console.warn("找不到衣服配置!状态："+s._sts+"-角色："+s._roleID);
				else
				{
					s._autoInvert = true;//s._clothes.autoInvert == 1;					
					s._action = s._actionConfig?s._actionConfig[sts]?s._actionConfig[sts]:s._actionConfig[0]:null;
					s._actionRate = s._action?s._action.rate[s._direction]?s._action.rate[s._direction]:s._action.rate[0]:null;
					if(s._actionRate && s._actionRate.duration)
						seqImg.actionDuration = s._actionRate.duration;
					direction = s._clothes.rate[s._direction] ? s._direction : 0;
					s._clothesRate = s._clothes.rate[direction];
					s.scaleForDir();
					seqImg.setConfig(s._clothes,s._direction,s._sts);
				}				
			}
			s.updateRateLoopFlag();
			s.setHeadH(s._clothes && s._clothes.headH != null ? s._clothes.headH : 120);
		}
		/**根据方向设定水平翻转*/
		protected scaleForDir(): void {
			let s = this;
			let isSpine: boolean = s._skinType == SkinType.SPINE;
			if (isSpine || s._autoInvert)//spine或者自动翻转的序列图
			{
				let sclX: number, sclY: number;
				sclX = s._dirScaleX < 0?-1:1;//默认保持原来的翻转
				sclY = 1;
				if (s._direction != map2D.DirectionType.UP && s._direction != map2D.DirectionType.DOWN)
					sclX = (map2D.DirectionType.isReserveDir(s._direction) ? -1 : 1);
				else
					sclX = sclX < 0 ? -1 : 1;
				s._dirScaleX = sclX;
				s._dirScaleY = sclY;
				s._scaleDir = sclX < 0 ? map2D.DirectionType.RIGHT : map2D.DirectionType.LEFT;
				// s.addSkinScale();
			}
			else {
				s._dirScaleX = 1;
				s._dirScaleY = 1;
			}
			// if (s.enabled3D && !isSpine) {
			// 	s._dirScaleX *= s._scaleX;
			// 	s._dirScaleY *= s._scaleY;
			// }

		}
		/**脚距离地平线的高度(即海拔高度)*/
		public get altitude():number
		{
			let s = this;
			return s._absZ + s._floatH;
		}
		public get floatH(): number {
			return this._floatH;
		}
		public set floatH(val: number) {
			this._floatH = val;
		}
		public setHeadH(val: number): void {
			let s = this;
			val = s._settingHeadH == s._settingHeadH ? s._settingHeadH : val;
			if(s._headH == val)return;
			s._headH = val;
			s.resetHeadJumpH();
		}
		public setRoleFloatH(val: number): void {
			let s = this;
			s._floatH = s._floatH - s._roleFloatH + val;
			s._roleFloatH = s.cfg.floatH = val;
		}
		public resetHeadJumpH() {
			let s = this;
			let scale: number = s.getSceneScale();
			s._headJumpH = s._headH * scale + s._absZ + s._floatH;
		}
		public get headH():number
		{
			let s= this;
			let scale: number = s.getSceneScale();
			return s._headH * scale;
		}	
		public create(createSts:number=StsType.STAND,createDir:number=0,x:number=0,y:number=0):void
		{let s = this;
			super.create(createSts,createDir,x,y);
			s._scene.addToSceneVec(s);
		}
		public reset(cfg:any=null):void
		{
			let s = this;
			s._isReset = true;
			s.parseConfig(s._roleType, cfg?cfg:s._cfg);			
		}		
		public setSts(sts:number=0,direction:number=-1):void
		{let s = this;
			direction = direction == -1?s._direction:direction;
			super.setSts(sts,direction);
			if(s._sts == sts && s._direction == direction && !StsType.attackAction(sts))return;			
			s._sts = sts;				
			s._direction = direction;			
			
			s.resetSkin(s._skinObj);
			
		}
		public setDirection(sts:number):void
		{
			let s = this;
			super.setDirection(sts);									
		}		
		/**执行状态切换*/
		protected doOperSts(): void {
			let s = this;			
			if (s._directSts > -1) {
				if (s._sts <= StsType.RUN || StsType.attackAction(s._sts))
					s.moveDir(map2D.DirectionType.angleArray[s._directSts]);
			}
			if (s._operSts > -1) {
				if(s._operSts != StsType.DEATH && s._sts == StsType.FALL)
				{
					s._operSts = -1;
					return;
				}
				if (s._operSts == StsType.RUN)
					s.moveDir(map2D.DirectionType.angleArray[s._directSts]);
				else
					s.setSts(s._operSts, s._direction);
				s._operSts = -1;
			}
			else if (s._skinPart.playEnd)
				s.resetSts();
		}	
		public enterLoop(t:number,index:number):void
		{
			let s= this;	
			super.enterLoop(t,index);			
			s.doOperSts();			
			if (s._rateLoopEnabled)
				s.actionSet();
		}
		public exitLoop(t:number,index:number):void
		{
			let s = this;	
			super.exitLoop(t,index);
			if (s.loopEnabled()) {
				if (s._autoRotate)
					s.setRotation(s._autoRotation);
				if (s._rateLoopEnabled)
					s._skinPart.loop(t);				
			}
			s.worldPosSet();	
		}
		/**帧循环标志更新*/
		public updateRateLoopFlag(): void {
			let s = this;
			s._rateLoopEnabled = s.rateLoopEnabled();
		}
		/**是否允许帧循环*/
		protected rateLoopEnabled(): boolean {
			let s = this;
			return s._skinType == SkinType.SPINE || s._skinType == SkinType.SEQ && s._skinPart._rateLen > 1;
		}
		/**执行动作帧数据*/
		protected actionSet(): void {
			let s = this;
			let rate: number, temp: number;
			let len: number, percent: number;
			percent = s._skinPart.curPercent;
			let actOffsetX: number[], actOffsetY: number[], actOffsetH: number[];
			let actInvert: number;
			let actionCfg: any;
			actInvert = 1;
			actionCfg = s._actionRate;
			if (actionCfg) {
				actOffsetX = actionCfg.offsetX;
				actOffsetY = actionCfg.offsetY;
				actOffsetH = actionCfg.offsetH;
			}
			else
				actOffsetX = actOffsetY = actOffsetH = null;

			if (actOffsetX) {
				len = actOffsetX && actOffsetX.length > 0 ? actOffsetX.length : 0;
				if (len > 0) {
					rate = percent * len | 0;
					temp = (rate < len ? actOffsetX[rate] : actOffsetX[len - 1]) * actInvert;
					if (temp != s._lastOffsetX) {
						s._absX = s._absX - s._lastOffsetX + temp;
						s._lastOffsetX = temp;
					}
				}
			}

			if (actOffsetY) {
				len = actOffsetY && actOffsetY.length > 0 ? actOffsetY.length : 0;
				if (len > 0) {
					rate = percent * len | 0;
					temp = rate < len ? actOffsetY[rate] : actOffsetY[len - 1];
					if (s._lastOffsetY != temp) {
						s._absY = s._absY - s._lastOffsetY + temp;
						s._lastOffsetY = temp;
					}
				}
			}

			if (actOffsetH) {				
				len = actOffsetH && actOffsetH.length > 0 ? actOffsetH.length : 0;
				if (len > 0) {
					rate = percent * len | 0;
					temp = rate < len ? actOffsetH[rate] : actOffsetH[len - 1];
					if (s._lastOffsetH != temp) {
						s._absZ = s._absZ - s._lastOffsetH + temp;						s._lastOffsetH = temp;
						s.resetHeadJumpH();						
					}
				}
			}
		}
		public loopEnabled(): boolean {
			return !this._scene._editabled;
		}		
		public resetSts():void
		{
			let s = this;
			s._stsChangeBeforeReset = false;
			if (s._stsEndCall) {
				s._stsEndCall.call(s._stsEndObj);
				s._stsEndCall = s._stsEndObj = null;
			}
			if (s._stsEndListener.length() > 0)
				s._stsEndListener.dataChange();
		}	
		public pause(): void {
			let s = this;
			s._paused = true;
			if (s._skinPart)
				s._skinPart.onPause();
		}
		public resume(): void {
			let s = this;
			s._paused = false;
			if (s._skinPart)
				s._skinPart.onResume();
		}		
		public beforeToPool(): void {
			let s = this;
			super.beforeToPool();
			
			s._stsEndListener.clear();
			s._stsEndCall = s._stsEndObj = null;
			
			if (s._roleEffects) {
				s._roleEffects.dispose();
				s._roleEffects = null;
			}
			if (s.roleEffectOwner)
				s.roleEffectOwner.roleEffMgr.invalidRoleEffect();
			
		}
		
		protected _clothesConfig:any;
		protected _actionConfig:any;
		protected _clothes:any;
		protected _action:any;		
		protected _clothesRate:any;		
		protected _actionRate:any;
		protected _stsChangeBeforeReset:boolean;
		protected _stsEndCall: Function;
		protected _stsEndObj: any;
		protected _rateLoopEnabled: boolean;
		public _stsEndListener: Listener;		
		/**是否自动翻转(单帧图不翻转)*/protected _autoInvert: boolean;
		/**本身角色的浮空高度*/
		public _roleFloatH: number;
		protected _roleEffects: RoleEffectMgr;
		public roleEffectOwner: RoleEffect;
		protected _lastOffsetX: number;
		protected _lastOffsetY: number;
		protected _lastOffsetH: number;
		
	}

}